home *** CD-ROM | disk | FTP | other *** search
/ Skunkware 5 / Skunkware 5.iso / src / Games / cbzone / c_move.c < prev    next >
C/C++ Source or Header  |  1995-05-03  |  18KB  |  734 lines

  1. #include "c_includes.h"
  2. /*
  3.  * cbzone_move.c
  4.  *  -- Todd W Mummert, December 1990, CMU
  5.  *
  6.  * RCS Info
  7.  *  $Header: c_move.c,v 1.1 91/01/12 02:03:35 mummert Locked $
  8.  *
  9.  * This file is largely based on the Fortran source by
  10.  * Justin S Revenaugh.  I've added the necessary information
  11.  * to handle multiple objects in placeobjects, but that's
  12.  * about it.  Moved any variables that were controlling
  13.  * an object that had to be static into the Generic structure.
  14.  */
  15.  
  16. void placeobjects(o, missilerun, score)
  17.      Genericp o;
  18.      Bool missilerun;
  19.      int score;
  20. {
  21.   static int lander = 1000;
  22.   static int landercount = 0;
  23.   static struct timeval clock = {0, 40000};
  24.   float odds, scale, r, dazm, ca, sa;
  25.   Genericp g;
  26.   Genericp pl = o;
  27.   int nta = 0;
  28.   int nsu = 0;
  29.   int nmi = 0;
  30.   int nco = 0;
  31.   int nla = 0;
  32.  
  33.   landercount++;
  34.   for (g=o; g<o+opt->mobjects; g++)
  35.     if (g->attr & STILL_THERE)
  36.       switch (g->type) {
  37.       case IS_TANK:
  38.         nta++; break;
  39.       case IS_SUPER:
  40.         nsu++; break;
  41.       case IS_MISSILE:
  42.         nmi++; break;
  43.       case IS_COPTER:
  44.         nco++; break;
  45.       case IS_LANDER:
  46.         nla++; break;
  47.       }
  48.  
  49.   if (pl->attr & IS_ALIVE &&
  50.       (missilerun && nta + nsu == 0 && nmi + nco < opt->mmissiles ||
  51.        !missilerun && nmi + nco == 0 && nta + nsu < opt->mtanks)) {
  52.     for (g=o+opt->estart; g<o+opt->lstart; g++)
  53.       if (!(g->attr & STILL_THERE))
  54.         break;
  55.     if (g == o+opt->lstart) {
  56.       printf("Help! Did not have space available for enemy!\n");
  57.       printf("Should not have been possible.\n");
  58.       exit(1);
  59.     }
  60.  
  61.     if (missilerun) {
  62.       /* reset clock usec just in case they change select to return the
  63.          amount of time remaining after the select finishes.   The
  64.          man page mentions this might occur in future releases.
  65.        */
  66.       tonetime();
  67.       clock.tv_usec = 40000;
  68.       select(0, 0, 0, 0, &clock);
  69.       tonetime();
  70.       clock.tv_usec = 40000;
  71.       select(0, 0, 0, 0, &clock);
  72.       tonetime();
  73.       odds = score / 500000.0;
  74.       if (score < 75000)
  75.         odds = 0.0;
  76.       if (odds > 0.333)
  77.         odds = 0.333;
  78.       if (opt->copters || frand() < odds) {
  79.         g->type = IS_COPTER;
  80.         g->lntype = LN_COPTER;
  81.         scale = 0.2;
  82.         g->z = 150.0;
  83.         r = 1900;
  84.       }
  85.       else {
  86.         g->type = IS_MISSILE;
  87.         g->lntype = LN_MISSILE;
  88.         scale = 0.1;
  89.         g->z = 250.0;
  90.         r = 1750;     
  91.       }
  92.       dazm = frand() * scale;
  93.       if (frand() > 0.5)
  94.         dazm = - dazm;
  95.       dazm += pl->azm;
  96.       ca = cos(dazm);
  97.       sa = sin(dazm);
  98.       g->x = pl->x - r * sa;
  99.       g->y = pl->y + r * ca;
  100.       g->attr = START_LIVING;
  101.       dazm = frand() * 0.015 / scale;
  102.       if (frand() > 0.5)
  103.         dazm = - dazm;
  104.       g->azm = pl->azm - PI + dazm;
  105.     }
  106.     else {
  107.       odds = (60000.0 - score) / 30000.0;
  108.       if (odds < 0.10)
  109.         odds = 0.10;
  110.       if (frand() < odds) {
  111.         g->type = IS_TANK;
  112.         g->lntype = LN_TANK;
  113.       }
  114.       else {
  115.         g->type = IS_SUPER;
  116.         g->lntype = LN_SUPER;
  117.       }
  118.       r = 800.0 + 1200.0 * frand();
  119.       dazm = frand() * PI2;
  120.       g->x = pl->x + r * cos(dazm);
  121.       g->y = pl->y + r * sin(dazm);
  122.       g->z = 0.0;
  123.       g->azm = frand() * PI2;
  124.       g->attr = START_LIVING;
  125.     }
  126.     g->criticalx = 45.0;
  127.     g->criticaly = 70.0;
  128.   }
  129.  
  130.   if (landercount > lander && nla < opt->mlanders) {
  131.     for (g=o+opt->lstart; g<o+opt->sstart; g++)
  132.       if (!(g->attr & STILL_THERE))
  133.         break;
  134.     if (g == o+opt->sstart) {
  135.       printf("Help! Did not have space available for lander!\n");
  136.       printf("Should not have been possible.\n");
  137.       exit(1);
  138.     }
  139.  
  140.     r = 1500.0 + 500.0 * frand();
  141.     dazm = frand() * PI2;
  142.     g->x = pl->x + r * cos(dazm);
  143.     g->y = pl->y + r * sin(dazm);
  144.     g->z = 0.0;
  145.     g->azm = frand() * PI2;
  146.     g->speed = frand() * 10.0;
  147.     g->criticalx = g->criticaly = 6400.0;
  148.     g->type = IS_LANDER;
  149.     g->lntype = LN_LANDER;
  150.     g->attr = START_LIVING;
  151.   }
  152.  
  153.   for (g=o+opt->bstart; g<o+opt->mobjects; g++)
  154.     if (!(g->attr & IS_ALIVE)) {
  155.       if (frand() > 0.5) {
  156.         g->type = IS_CUBE;
  157.         g->lntype = LN_CUBE;
  158.         g->criticalx = g->criticaly = 50.0;
  159.       }
  160.       else {
  161.         g->type = IS_PYRAMID;
  162.         g->lntype = LN_PYRAMID;
  163.         g->criticalx = g->criticaly = 35.0;
  164.       }
  165.       g->attr = START_LIVING;
  166.       if (pl->attr & IS_NEW)
  167.         r = 400 + frand() * 1800.0;
  168.       else
  169.         r = 2000.0;
  170.       dazm = frand() * PI2;
  171.       g->x = pl->x + r * cos(dazm);
  172.       g->y = pl->y + r * sin(dazm);
  173.       g->z = 0.0;
  174.     }
  175. }
  176.  
  177. void movesuper(g, pl)
  178.      Genericp g;
  179.      Genericp pl;
  180. {
  181.   int i;
  182.   float dx, dy, tazm, t1, t3, scrot, sctot, scale, cp, sp, dcp;
  183.   float dsp, cm, sm, xmt, ymt, xpt, ypt, rate, temp, dist;
  184.   Genericp s;
  185.   
  186.   g->pcount++;
  187.   g->fcount++;
  188.   if (g->attr & IS_NEW) {
  189.     g->attr &=  ~(IS_NEW | IS_PRESET);
  190.     g->bcount = 0;
  191.     g->ecount = 0;
  192.     g->pcount = 10;
  193.     g->fcount = 15;
  194.     g->orientation = 1.0;
  195.   }
  196.   if (g->attr & IS_BLOCKED && g->attr & LAST_BLOCKED)
  197.     g->orientation = -g->orientation;
  198.   g->attr &= ~LAST_BLOCKED;
  199.   
  200.   if (g->attr & IS_BLOCKED) {
  201.     if (g->attr & BLOCKED_BY_ENEMY)
  202.       g->attr |= IS_EVADING;
  203.     else 
  204.       g->attr &= ~IS_EVADING;
  205.     g->attr |= IS_PRESET | LAST_BLOCKED;
  206.     g->bcount  = 0;
  207.   }
  208.   if (g->attr & IS_PRESET) {
  209.     g->bcount++;
  210.     if (!(g->attr & IS_EVADING)) {
  211.       if (g->bcount == 1) {
  212.         g->speed = -12.0 * g->orientation;
  213.         g->rotate = 0.045;
  214.         if (frand() > 0.5)
  215.           g->rotate = -g->rotate;
  216.       }
  217.       else if (g->bcount == 30) {
  218.         g->speed  = 12.0 * g->orientation;
  219.         g->rotate = 0.0;
  220.       }
  221.       else if (g->bcount > 60)
  222.         g->attr &= ~IS_PRESET;
  223.     }
  224.     else {
  225.       if (g->bcount == 1) {
  226.         g->speed  = -12.0 * g->orientation;
  227.         g->rotate = 0.0;
  228.       }
  229.       else if (g->bcount == 10 || g->bcount == 15 ||
  230.                g->bcount == 20 || g->bcount == 25) {
  231.         dx = pl->x - g->x;
  232.         dy = pl->y - g->y;
  233.         if (fabs(dy) < 1.e-7)
  234.           dy = sign(1.e-7, dy);
  235.         if (dy <= 0.0)
  236.           tazm = - atan(dx / dy) + ra (180.0);
  237.         else
  238.           tazm = - atan(dx / dy) ;
  239.         if (g->azm > PI2)
  240.           g->azm -= PI2;
  241.         if (g->azm < 0.0)
  242.           g->azm += PI2;
  243.         t1 = (tazm - g->azm) / 5.0;
  244.         t3 = (tazm - (g->azm - PI2)) / 5.0;
  245.         if (fabs(t3) < fabs(t1))
  246.           t1 = t3;
  247.         if (fabs(t1) > 0.045)
  248.           t1 = sign (.045, t1);
  249.         g->rotate = t1;
  250.         g->speed = 0.0;
  251.       }
  252.       else if (g->bcount > 30)
  253.         g->attr &= ~IS_PRESET;
  254.     }
  255.   }
  256.   else if (g->pcount >= 5) {
  257.     g->orientation = 1.0;
  258.     g->pcount = 0;
  259.     dx = pl->x - g->x;
  260.     dy = pl->y - g->y;
  261.     if (fabs(dy) < 1.e-7) dy =
  262.       sign(1.e-7, dy);
  263.     if (dy <= 0.0) 
  264.       tazm = - atan(dx / dy) + ra (180.0);
  265.     else
  266.       tazm = - atan(dx / dy);
  267.     if (g->azm > PI2)
  268.       g->azm -= PI2;
  269.     if (g->azm < 0.0)
  270.       g->azm += PI2;
  271.     t1 = (tazm - g->azm) / 5.0;
  272.     t3 = (tazm - (g->azm - PI2)) / 5.0;
  273.     if (fabs(t3) < fabs(t1))
  274.       t1 = t3;
  275.     g->speed = 12.0 * (PI - fabs(t1) * 5.0) / PI;
  276.     if (fabs(t1) > 0.045)
  277.       t1 = sign (0.045, t1);
  278.     g->rotate = t1;
  279.   }
  280.  
  281.   scrot = g->rotate / 0.045 * 12.0;
  282.   sctot = sqrt (g->speed*g->speed + scrot*scrot);
  283.   if (sctot > 12.0) {
  284.     scale = 12.0 / sctot;
  285.     g->speed *= scale;
  286.     g->rotate *= scale;
  287.   }
  288.  
  289.   s = g->salvo;
  290.   if (pl->attr & IS_ALIVE && g->fcount>10 && g->ecount>50 &&
  291.       !(s->attr & STILL_THERE)) { 
  292.     g->fcount = 0;
  293.     cp = pl->ca;
  294.     sp = pl->sa;
  295.     dcp = cos(pl->rotate);
  296.     dsp = sin(pl->rotate);
  297.     cm = cos(g->azm);
  298.     sm = sin(g->azm);
  299.     i = 0;
  300.     xmt = g->x;
  301.     ymt = g->y;
  302.     xpt = pl->x;
  303.     ypt = pl->y;
  304.     rate = 40.0;
  305.  
  306.     for (i=0; i<50; i++) {
  307.       temp = cp;
  308.       cp = cp * dcp - sp * dsp;
  309.       sp = sp * dcp + dsp * temp;
  310.       xmt -= sm * rate;
  311.       ymt += cm * rate;
  312.       xpt -= sp * pl->speed;
  313.       ypt += cp * pl->speed;
  314.       dist = (xpt-xmt)*(xpt-xmt) + (ymt-ypt)*(ymt-ypt);
  315.       if (dist <= BMS_TOL) {
  316.         s->attr = START_LIVING;
  317.         s->x = g->x;
  318.         s->y = g->y;
  319.         s->z = 0.0;
  320.         s->prox = g->prox;
  321.         s->proy = g->proy;
  322.         s->azm = g->azm;
  323.         s->speed = 40.0;       
  324.         s->ecount = 0;                  
  325.         message(3, True);
  326.         break;
  327.       }
  328.     }
  329.   }
  330. }
  331.  
  332. void movemissile(g, pl, first)
  333.      Genericp g;
  334.      Genericp pl;
  335.      Bool first;
  336. {
  337.   float dx, dy, tazm, t1, t3, dt1, t2;
  338.  
  339.   if (g->attr & IS_NEW) {
  340.     g->ecount = 0;
  341.     g->pcount = 0;
  342.     g->attr &= ~IS_NEW;
  343.   }
  344.     
  345.   g->rotate = 0.0;
  346.   g->pcount++;
  347.   g->z -= 25.0;
  348.   if (g->z <= 0.0)
  349.     g->z = 0.0;
  350.   if (g->attr & IS_BLOCKED)
  351.     g->z = 90.0;
  352.   g->speed = 35.0;
  353.   if (g->z > 91.0)
  354.     g->speed = 0.0;
  355.   if (g->pcount >= 12) {
  356.     g->pcount = 0;
  357.     if (g->proy > 60.0) {
  358.       dx = pl->x - g->x;
  359.       dy = pl->y - g->y;
  360.       if (fabs(dy) < 1.e-7)
  361.         dy = sign(1.e-7, dy);
  362.       if (dy <= 0.0) 
  363.         tazm = - atan(dx / dy) + ra (180.0);
  364.       else
  365.         tazm = - atan(dx / dy);
  366.       if (g->azm > PI2)
  367.         g->azm -= PI2;
  368.       if (g->azm < 0.0)
  369.         g->azm += PI2;
  370.       t1 = (tazm - g->azm);
  371.       t3 = (tazm - (g->azm - PI2));
  372.       if (fabs(t3) < fabs(t1))
  373.         t1 = t3;
  374.       if (!first) {
  375.         dt1 = frand() * 0.5;
  376.         dt1 = sign (dt1, t1);
  377.         if (frand() > 0.8)
  378.           dt1 = - dt1;
  379.         t1 += dt1;
  380.       }
  381.       if (fabs(t1) > 0.90)
  382.         t1 = sign (0.90, t1);
  383.       g->rotate = t1;
  384.     }
  385.     else {
  386.       tazm = pl->azm - PI;
  387.       if (tazm < 0.0)
  388.         tazm += PI2;
  389.       if (tazm > PI2)
  390.         tazm -= PI2;
  391.       if (g->azm < 0.0)
  392.         g->azm += PI2;
  393.       if (g->azm > PI2)
  394.         g->azm -= PI2;
  395.       t1 = (tazm - g->azm);
  396.       t2 = (tazm - (g->azm - PI2));
  397.       if (fabs(t2) < fabs(t1))
  398.         t1 = t2;
  399.       if (fabs(t1) > 0.90)
  400.         t1 = sign (0.90, t1);
  401.       g->rotate = t1;  
  402.     }
  403.   }
  404. }
  405.  
  406. void movecopter(g, pl)
  407.      Genericp g;
  408.      Genericp pl;
  409. {
  410.   float dx, dy, tazm, t1, t2, t3, cp, sp, dcp, dsp, cm, sm;
  411.   float xmt, ymt, xpt, ypt, rate, temp, dist;
  412.   int i;
  413.   Genericp s;
  414.   
  415.   g->pcount++;
  416.   if (!(pl->attr & IS_ALIVE)) {
  417.     g->pcount = 0;
  418.     g->attr &= ~CAN_SHOOT;
  419.   }
  420.   
  421.   if (g->attr & IS_NEW) {
  422.     g->pcount = 10;
  423.     g->ecount = 0;
  424.     g->attr |= CAN_SHOOT;
  425.     g->attr &= ~IS_NEW;
  426.     if (frand() > 0.5) 
  427.       g->orientation = PI / 2.0;
  428.     else
  429.       g->orientation = -PI / 2.0;
  430.   }
  431.  
  432.   s = g->salvo;
  433.   if (g->ecount < 150 && g->range > 400.0)
  434.     if (!(s->attr & STILL_THERE))
  435.       g->z -= 5.0;
  436.     else
  437.       g->z += 5.0;
  438.   else
  439.     g->z += 5.0;
  440.  
  441.   if (g->z <= 40.0)
  442.     g->z = 40.0;
  443.   if (g->z > 150.0)
  444.     g->z = 150.0;
  445.   if (g->attr & IS_BLOCKED && g->z < 90.0) {
  446.     g->z = 90.0;
  447.     g->attr &= ~IS_BLOCKED;
  448.   }
  449.  
  450.   g->speed = 20.0;
  451.   if (g->pcount >= 10) {
  452.     g->pcount = 0;
  453.     if (g->range > 400.0 && g->ecount < 150) {
  454.       dx = pl->x - g->x;
  455.       dy = pl->y - g->y;
  456.       if (fabs(dy) < 1.e-7)
  457.         dy = sign(1.e-7, dy);
  458.       if (dy <= 0.0) 
  459.         tazm = - atan(dx / dy) + ra (180.0);
  460.       else
  461.         tazm = - atan(dx / dy);
  462.       if (g->azm > PI2)
  463.         g->azm -= PI2;
  464.       if (g->azm < 0.0)
  465.         g->azm += PI2;
  466.       t1 = (tazm - g->azm) / 10.0;
  467.       t3 = (tazm - (g->azm - PI2)) /10.0;
  468.       if (fabs(t3) < fabs(t1))
  469.         t1 = t3;
  470.       if (fabs(t1) > 0.06)
  471.         t1 = sign (0.06, t1);
  472.       g->rotate = t1;
  473.     }
  474.     else { 
  475.       tazm = g->orientation;
  476.       if (tazm < 0.0)
  477.         tazm += PI2;
  478.       if (tazm > PI2)
  479.         tazm -= PI2;
  480.       if (g->azm < 0.0)
  481.         g->azm += PI2;
  482.       if (g->azm > PI2)
  483.         g->azm -= PI2;
  484.       t1 = (tazm - g->azm) / 10.0;
  485.       t2 = (tazm - (g->azm - PI2)) / 10.0;
  486.       if (fabs(t2) < fabs(t1))
  487.         t1 = t2;
  488.       if (fabs(t1) > 0.06)
  489.         t1 = sign (0.06, t1);
  490.       g->rotate = t1;
  491.       g->speed = 30.0;
  492.     }
  493.   }
  494.   
  495.   if (g->attr & CAN_SHOOT && g->z < 50.0 &&
  496.       !(s->attr & STILL_THERE)) {
  497.     /*
  498.      * the original Fortran had the following
  499.      *    sp = pl->sa     and    cp = pl->ca
  500.      *
  501.      * however, sa and ca were undefined...fortran was really good
  502.      * about making these 0, C doesn't guarantee this will occur.
  503.      * the two choices to fix this are to make sp and cp
  504.      * 0 initially or to make them the sin/cos of azm.
  505.      * the first method makes the copter fire as it hits
  506.      * the ground, the second method the copter won't fire
  507.      * until it is very close unless you are moving straight
  508.      * toward it or straight away from it.
  509.      */
  510.     cp = sp = 0;
  511.     dcp = cos(pl->rotate);
  512.     dsp = sin(pl->rotate);
  513.     cm = cos(g->azm);
  514.     sm = sin(g->azm);
  515.     xmt = g->x;
  516.     ymt = g->y;
  517.     xpt = pl->x;
  518.     ypt = pl->y;
  519.     rate = 40.0;
  520.     
  521.     for (i=0; i<50; i++) {
  522.       temp = cp;
  523.       cp = cp * dcp - sp * dsp;
  524.       sp = sp * dcp + dsp * temp;
  525.       xmt -= sm * rate;
  526.       ymt += cm * rate;
  527.       xpt -= sp * pl->speed;
  528.       ypt += cp * pl->speed;
  529.       dist = (xpt-xmt)*(xpt-xmt) + (ymt-ypt)*(ymt-ypt);
  530.       if (dist <= BMC_TOL) {
  531.         s->attr = START_LIVING;
  532.         s->x = g->x;
  533.         s->y = g->y;
  534.         s->z = 0.0;
  535.         s->prox = g->prox;
  536.         s->proy = g->proy;
  537.         s->azm = g->azm;
  538.         s->speed = 40.0;
  539.         s->ecount = 0;
  540.         message(3, True);
  541.         break;
  542.       }
  543.     }
  544.   }
  545. }
  546.  
  547. void movetank(g, pl)
  548.      Genericp g;
  549.      Genericp pl;
  550. {
  551.   int i;
  552.   float dx, dy, tazm, t1, t3, scrot, sctot, scale, cp, sp, dcp;
  553.   float dsp, cm, sm, xmt, ymt, xpt, ypt, rate, temp, dist;
  554.   Genericp s;
  555.   
  556.   g->pcount++;
  557.   g->fcount++;
  558.   if (g->attr & IS_NEW) {
  559.     g->attr &= ~(IS_NEW | IS_PRESET);
  560.     g->bcount = 0;
  561.     g->ecount = 0;
  562.     g->pcount = 5;
  563.     g->fcount = 5;
  564.     g->orientation = 1.0;
  565.   }
  566.   if (g->attr & IS_BLOCKED && g->attr & LAST_BLOCKED)
  567.     g->orientation = -g->orientation;
  568.   g->attr &= ~LAST_BLOCKED;
  569.   
  570.   if (g->attr & IS_BLOCKED) {
  571.     if (g->attr & BLOCKED_BY_ENEMY)
  572.       g->attr |= IS_EVADING;
  573.     else 
  574.       g->attr &= ~IS_EVADING;
  575.     g->attr |= IS_PRESET | LAST_BLOCKED;
  576.     g->bcount  = 0;
  577.   }
  578.  
  579.   if (g->attr & IS_PRESET) {
  580.     g->bcount++;
  581.     if (!(g->attr & IS_EVADING)) {
  582.       if (g->bcount == 1) {
  583.         g->speed = -8.0 * g->orientation;
  584.         g->rotate = 0.030;
  585.         if (frand() > 0.5)
  586.           g->rotate = -g->rotate;
  587.       }
  588.       else if (g->bcount == 45) {
  589.         g->speed  = 8.0 * g->orientation;
  590.         g->rotate = 0.0;
  591.       }
  592.       else if (g->bcount > 90)
  593.         g->attr &= ~IS_PRESET;
  594.     }
  595.     else {
  596.       if (g->bcount == 1) {
  597.         g->speed  = -8.0 * g->orientation;
  598.         g->rotate = 0.0;
  599.       }
  600.       else if (g->bcount == 10 || g->bcount == 15 ||
  601.                g->bcount == 20 || g->bcount == 25) {
  602.         dx = pl->x - g->x;
  603.         dy = pl->y - g->y;
  604.         if (fabs(dy) < 1.e-7)
  605.           dy = sign(1.e-7, dy);
  606.         if (dy <= 0.0)
  607.           tazm = - atan(dx / dy) + ra (180.0);
  608.         else
  609.           tazm = - atan(dx / dy) ;
  610.         if (g->azm > PI2)
  611.           g->azm -= PI2;
  612.         if (g->azm < 0.0)
  613.           g->azm += PI2;
  614.         t1 = (tazm - g->azm) / 5.0;
  615.         t3 = (tazm - (g->azm - PI2)) / 5.0;
  616.         if (fabs(t3) < fabs(t1))
  617.           t1 = t3;
  618.         if (fabs(t1) > 0.030)
  619.           t1 = sign (.030, t1);
  620.         g->rotate = t1;
  621.         g->speed = 0.0;
  622.       }
  623.       else if (g->bcount > 30)
  624.         g->attr &= ~IS_PRESET;
  625.     }
  626.   }
  627.   else if (g->pcount >= 10) {
  628.     g->orientation = 1.0;
  629.     g->pcount = 0;
  630.     dx = pl->x - g->x;
  631.     dy = pl->y - g->y;
  632.     if (fabs(dy) < 1.e-7)
  633.       dy = sign(1.e-7, dy);
  634.     if (dy <= 0.0) 
  635.       tazm = - atan(dx / dy) + ra (180.0);
  636.     else
  637.       tazm = - atan(dx / dy);
  638.     if (g->azm > PI2)
  639.       g->azm -= PI2;
  640.     if (g->azm < 0.0)
  641.       g->azm += PI2;
  642.     t1 = (tazm - g->azm) / 10.0;
  643.     t3 = (tazm - (g->azm - PI2)) / 10.0;
  644.     if (fabs(t3) < fabs(t1))
  645.       t1 = t3;
  646.     g->speed = 8.0 * (PI - fabs(t1) * 10.0) / PI;
  647.     if (fabs(t1) > 0.030)
  648.       t1 = sign (0.030, t1);
  649.     g->rotate = t1;
  650.   }
  651.  
  652.   scrot = g->rotate / 0.030 * 8.0;
  653.   sctot = sqrt (g->speed*g->speed + scrot*scrot);
  654.   if (sctot > 8.0) {
  655.     scale = 8.0 / sctot;
  656.     g->speed *= scale;
  657.     g->rotate *= scale;
  658.   }
  659.  
  660.   s = g->salvo;
  661.   if (pl->attr & IS_ALIVE && g->fcount>10 && g->ecount>100 &&
  662.       !(s->attr & STILL_THERE)) {
  663.     g->fcount = 0;
  664.     cp = pl->ca;
  665.     sp = pl->sa;
  666.     dcp = cos(pl->rotate);
  667.     dsp = sin(pl->rotate);
  668.     cm = cos(g->azm);
  669.     sm = sin(g->azm);
  670.     i = 0;
  671.     xmt = g->x;
  672.     ymt = g->y;
  673.     xpt = pl->x;
  674.     ypt = pl->y;
  675.     rate = 40.0;
  676.  
  677.     for (i=0; i<50; i++) {
  678.       temp = cp;
  679.       cp = cp * dcp - sp * dsp;
  680.       sp = sp * dcp + dsp * temp;
  681.       xmt -= sm * rate;
  682.       ymt += cm * rate;
  683.       xpt -= sp * pl->speed;
  684.       ypt += cp * pl->speed;
  685.       dist = (xpt-xmt)*(xpt-xmt) + (ymt-ypt)*(ymt-ypt);
  686.       if (dist <= BMT_TOL) {
  687.         s->attr = START_LIVING;
  688.         s->x = g->x;
  689.         s->y = g->y;
  690.         s->z = 0.0;
  691.         s->prox = g->prox;
  692.         s->proy = g->proy;
  693.         s->azm = g->azm;
  694.         s->speed = 40.0;       
  695.         s->ecount = 0;                  
  696.         message(3, True);
  697.         break;
  698.       }
  699.     }
  700.   }
  701. }
  702.  
  703. void movelander(g, pl)
  704.      Genericp g;
  705.      Genericp pl;
  706. {
  707.   float dx, dy, theta;
  708.   
  709.   if (++g->pcount > 20) {
  710.     g->pcount = 0;
  711.  
  712.     if (g->range <= 750.0) {
  713.       dx = g->x - pl->x;
  714.       dy = g->y - pl->y;
  715.       theta = atan (dy / (fabs(dx) + 1.0));
  716.       if (dx <= 0.0)
  717.         theta = PI - theta;
  718.       /* the original fortran went to all the trouble of calculating
  719.        * theta above, but never used it.  perhaps the following
  720.        * statement was left out.
  721.        */
  722.       g->azm = theta;
  723.     }
  724.     
  725.     if (frand() >= 0.5) {
  726.       g->azm += frand() * PI / 4.0;
  727.     }
  728.     else {
  729.       g->azm -= frand() * PI / 4.0;
  730.     }
  731.     g->speed = frand() * 20.0;
  732.   }
  733. }
  734.